﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace TienLen
{
    /* Custom component of TreeView which allows multi-selecting of nodes (only roots of nodes will work)
     * 
     * Thanks to http://www.arstdesign.com/articles/treeviewms.html for the useful article. This was used to
     * partially make up this custom component. */

    /// <summary>
    /// A custom TreeView control which allows multi-selection.
    /// </summary>
    public partial class MultiTreeView : TreeView
    {
        private List<TreeNode> selnodes = new List<TreeNode>();
        private TreeNode lastnode;

        public MultiTreeView()
        {
            InitializeComponent();
        }

        public MultiTreeView(IContainer container)
        {
            container.Add(this);
            InitializeComponent();
        }

        public List<TreeNode> SelectedNodes
        {
            get { return selnodes; }
        }

        public void RemoveSelectedNodes()
        {
            foreach (TreeNode nodes in selnodes)
                this.Nodes.Remove(nodes);

            selnodes.Clear();
        }

        public void DeselectNode(TreeNode node)
        {
            node.BackColor = this.BackColor;
            node.ForeColor = this.ForeColor;
        }

        protected override void OnBeforeSelect(System.Windows.Forms.TreeViewCancelEventArgs e)
        {
           base.OnBeforeSelect(e);

           if (ModifierKeys == Keys.Control)
           {
               if (IsSelected(e.Node) && selnodes.Count != 1)
               {
                   ClearSelectedNodes(e.Node);
                   return;
               }
               else
               {
                   selnodes.Add(e.Node);
               }
           }
           else if (ModifierKeys == Keys.Shift)
           {
               if (lastnode != null)
               {
                   for (int x = lastnode.Index; x <= e.Node.Index ; x++)
                       selnodes.Add(this.Nodes[x]);
               }
           }
           else
           {
               ClearSelectedNodes();
               selnodes.Add(e.Node);
           }

           PaintSelectedNodes();
        }

        protected override void OnAfterSelect(TreeViewEventArgs e)
        {
            base.OnAfterSelect(e);

            lastnode = this.SelectedNode;
            this.SelectedNode = null;
        }

        private bool IsSelected(TreeNode node)
        {
            return (node.BackColor == SystemColors.Highlight && node.ForeColor == SystemColors.HighlightText);
        }

        private void PaintSelectedNodes()
        {
            foreach (TreeNode nodes in selnodes)
            {
                nodes.BackColor = SystemColors.Highlight;
                nodes.ForeColor = SystemColors.HighlightText;
            }
        }

        private void ClearSelectedNodes()
        {
            foreach (TreeNode node in selnodes)
            {
                node.BackColor = this.BackColor;
                node.ForeColor = this.ForeColor;
            }

            selnodes.Clear();
        }

        private void ClearSelectedNodes(TreeNode node)
        {
            node.BackColor = this.BackColor;
            node.ForeColor = this.ForeColor;

            selnodes.Remove(node);
        }
    }
}
